package org.smoozik.app.settings;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.border.TitledBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import org.smoozik.app.ihm.Constants;
import org.smoozik.app.ihm.Smoozik;
import org.smoozik.app.mode.Mode;

@SuppressWarnings("serial")
public class SettingsFrame extends JDialog implements ActionListener {
	private Smoozik parent;
	private JComboBox<String> modeCombo;
	private JTextField volumeTextField;

	private JPanel centerPanel;
	private JPanel currentPanel;

	private JTree createTree() {

		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Smoozik");
		rootNode.setUserObject(new MainSettings());

		DefaultMutableTreeNode parentNode;
//		parentNode = createDefaultNodes();
//		rootNode.add(parentNode);

		parentNode = createModeNodes();
		rootNode.add(parentNode);

		JTree tree = new JTree(rootNode);

		tree.addTreeSelectionListener(new TreeSelectionListener() {
			public void valueChanged(TreeSelectionEvent e) {
				TreePath path = e.getNewLeadSelectionPath();
				Object lastElement = path.getLastPathComponent();
				DefaultMutableTreeNode node;

				if (lastElement instanceof DefaultMutableTreeNode) {
					node = (DefaultMutableTreeNode) lastElement;
					Object userObject = node.getUserObject();
					if (userObject instanceof Mode) {
						replaceCurrentPanel(((Mode) userObject)
								.getModeSettings().getMainPanel());
					} else if (userObject instanceof MainSettings) {
						replaceCurrentPanel(((MainSettings) userObject)
								.getMainPanel());
					}
				}

//				System.out.println(path.toString());
				revalidate();
				repaint();
			}
		});

		tree.setSelectionPath(new TreePath(rootNode.getPath()));

		return tree;
	}

	private void replaceCurrentPanel(JPanel panel) {
		if (currentPanel != null) {
			centerPanel.remove(currentPanel);
		}
		currentPanel = panel;
		centerPanel.add(currentPanel);
	}

	public DefaultMutableTreeNode createDefaultNodes() {

		DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(
				"General");
		parentNode.setUserObject(new MainSettings());
		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Keybord");
		parentNode.add(node);
		node = new DefaultMutableTreeNode("Mixer");
		parentNode.add(node);

		return parentNode;
	}

	public DefaultMutableTreeNode createModeNodes() {

		DefaultMutableTreeNode parentNode;
		DefaultMutableTreeNode node;

		parentNode = new DefaultMutableTreeNode("Modes");
		// Add the mode panel in the center panel
		for (Mode mode : this.parent.getModes()) {
			if (mode != null) {
				node = new DefaultMutableTreeNode(mode.toString());
				node.setUserObject(mode);
				parentNode.add(node);
			}
		}

		return parentNode;
	}

	private JPanel createButtonsPane() {
		JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		JButton okButton = new JButton(Constants.OK_LABEL);
		JButton cancelButton = new JButton(Constants.CANCEL_LABEL);

		okButton.addActionListener(this);
		cancelButton.addActionListener(this);

		buttonsPanel.add(okButton);
		buttonsPanel.add(cancelButton);

		return buttonsPanel;
	}

	public SettingsFrame(Smoozik frame) {
		super(frame, Constants.SETTINGS_LABEL, true);

		JPanel topLevelPane = new JPanel(new BorderLayout());
		// JPanel mainPanel;

		this.parent = frame;

		// mainPanel = createMainSettingsPane();

		centerPanel = new JPanel();
		centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));

		// Add the main Panel in the center panel
		// centerPanel.add(mainPanel);

		// Add the mode panel in the center panel
		// for (Mode mode : this.parent.getModes()) {
		// if (mode != null) {
		// centerPanel.add(mode.getModeSettings().getMainPanel());
		// }
		// }

		topLevelPane.add(createTree(), BorderLayout.WEST);
		topLevelPane.add(centerPanel, BorderLayout.CENTER);
		topLevelPane.add(createButtonsPane(), BorderLayout.SOUTH);
		topLevelPane.setBackground(Color.black);

		add(topLevelPane);

		// Display the window.
		pack();
		setSize(800, 500);

		ActionListener escapeListener = new ActionListener() {
			public void actionPerformed(ActionEvent actionEvent) {
				setVisible(false);
			}
		};
		ActionListener enterListener = new ActionListener() {
			public void actionPerformed(ActionEvent actionEvent) {
				saveParameter();
			}
		};
		int c = JComponent.WHEN_IN_FOCUSED_WINDOW;
		KeyStroke ksEscape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
		topLevelPane.registerKeyboardAction(escapeListener, ksEscape, c);
		KeyStroke ksEnter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
		topLevelPane.registerKeyboardAction(enterListener, ksEnter, c);
		refreshParams();
	}

	public void refreshParams() {
		modeCombo.setSelectedItem(this.parent.getParamMode());
		volumeTextField.setText("" + this.parent.getVolume());

		if (parent != null && parent.getModes() != null) {
			for (Mode m : parent.getModes()) {
				m.getModeSettings().refreshParameters();
			}
		}

	}

	private void addComponent(JPanel origine, String text, Component component) {
		JPanel panel = new JPanel();
		if (text != null) {
			JLabel label = new JLabel(text);
			panel.add(label);
		}
		panel.add(component);
		origine.add(panel);
	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();
		if (source instanceof JButton) {
			JButton button = (JButton) source;
			String labelButton = button.getText();
			if (Constants.OK_LABEL.equals(labelButton)) {
				saveParameter();
			} else if (Constants.CANCEL_LABEL.equals(labelButton)) {
				setVisible(false);
			}
		}
	}

	public void saveParameter() {

		// Game properties
		String mode = (String) modeCombo.getSelectedItem();
		this.parent.updateMode(mode);
		// Volume
		if (volumeTextField.getText() != null
				&& volumeTextField.getText().trim().length() != 0) {
			this.parent.setVolume(Float.parseFloat(volumeTextField.getText()));
		}

		if (parent != null && parent.getModes() != null) {
			for (Mode m : parent.getModes()) {
				m.getModeSettings().saveParameters();
			}
		}

		setVisible(false);
	}

	public class MainSettings {
		JPanel mainPanel;

		public MainSettings() {
			mainPanel = createMainSettingsPanel();
		}

		public JPanel getMainPanel() {
			return mainPanel;
		}

		public void setMainPanel(JPanel mainPanel) {
			this.mainPanel = mainPanel;
		}

		
		private JPanel createMainSettingsPanel() {

			JPanel mainPanel = new JPanel();
			mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

			JPanel modePanel = new JPanel();
			modePanel.setBorder(new TitledBorder("Mode"));
			modeCombo = new JComboBox<String>();
			modeCombo.addItem(Constants.LINE_TRAINER_ID);
			modeCombo.addItem(Constants.GENERATOR_ID);
			modeCombo.addItem(Constants.RYTHMTRAINER_ID);
			addComponent(modePanel, Constants.MODE_LABEL, modeCombo);

			JPanel systemPanel = new JPanel();
			systemPanel.setBorder(new TitledBorder("System"));
			volumeTextField = new JTextField(15);
			addComponent(systemPanel, Constants.VOLUME_LABEL, volumeTextField);

			mainPanel.add(systemPanel);
			mainPanel.add(modePanel);

			return mainPanel;
		}

		public String toString() {
			return "General";
		}

	}

}
